#include "DoABCTreeItem.h"
#include "editor/Icon.h"
#include "swf/tags/TagDoABC.h"
#include "swf/abc/ABCFile.h"
#include <vector>

DoABCTreeItem::DoABCTreeItem( AS3ABCFile* abc )
	: _abc(abc)
	, _categoryInit(false)
	, _classItem(nullptr)
	, SWFTreeItem(abc->getName().c_str())
{
	_kind = SWFTreeItemKind::DoABC;
	if (abc->getClassCount() > 0)
	{
		this->setIcon(Icon::getDoABC());
	}
	else
	{
		this->setIcon(*Icon::getIcon(Icon::kMethod, Icon::IconTrait::kFinal));
	}
}

bool DoABCTreeItem::hasChildren() const 
{
	return true;
}

void DoABCTreeItem::beforeRequestChildCount()
{
	if (_categoryInit == false)
	{
		//_poolItem = new CpoolInfoItem(_abc->abcFile->poolInfo);
		//_poolItem->setIcon(Icon::getCpool());
		//this->appendRow(_poolItem);
		_abc->analyze();
		std::vector<AS3Class*> classesVec;
		_abc->getAllClasses(classesVec);
		_categoryInit = true;
		for (AS3Class* clazz : classesVec)
		{
			_classItem = new SWFClassItem(clazz);
			this->appendRow(_classItem);
		}
	}
}

QMenu* DoABCTreeItem::requestContextMenu()
{
	QMenu* menu = new QMenu();
	menu->addAction(_abc->getName().c_str());
	return menu;
}

SWFClassItem::SWFClassItem( AS3Class* c )
	: _clazz(c)
{
	this->setName(c->getShortName());
	this->setIcon(c->isInterface() ? Icon::getInterface() : Icon::getClass());
}

void SWFClassItem::beforeRequestChildCount()
{
	if (this->childCount() > 0)
		return;
	std::vector<AS3Slot*> slotsVec;
	_clazz->getAllSlots(slotsVec);
	for (AS3Slot* slot : slotsVec)
	{
		SWFTreeItem* item = new SWFTreeItem(slot->getShortName().c_str());
		int iconTrait;
		if (slot->isPublic())
			iconTrait = Icon::kPublic;
		else if (slot->isPrivate())
			iconTrait = Icon::kPrivate;
		else
			iconTrait = Icon::kProtected;

		if (slot->isConst()) iconTrait |= Icon::kConst;
		if (slot->isStatic()) iconTrait |= Icon::kStatic;

		item->setIcon(*Icon::getIcon(Icon::kField, iconTrait));
		item->setUserData(slot);
		this->appendRow(item);
	}

	std::vector<AS3Method*> methodsVec;
	_clazz->getAllMethods(methodsVec);
	for (AS3Method* method : methodsVec)
	{
		SWFTreeItem* item = new SWFTreeItem(method->getShortName().c_str());
		int iconTrait;
		if (method->isPublic() || _clazz->isInterface())
			iconTrait = Icon::kPublic;
		else if (method->isPrivate())
			iconTrait = Icon::kPrivate;
		else
			iconTrait = Icon::kProtected;

		Icon::Kind kind = Icon::kMethod;
		if (method->isGetter())
			kind = Icon::kGetter;
		else if (method->isSetter())
			kind = Icon::kSetter;

		if (method->isFinal()) iconTrait |= Icon::kFinal;
		if (method->isStatic()) iconTrait |= Icon::kStatic;
		item->setIcon(*Icon::getIcon(kind, iconTrait));
		item->setKind(SWFTreeItemKind::Method);
		item->setUserData(method);
		this->appendRow(item);
	}
}

bool SWFClassItem::hasChildren() const 
{
	return true;
}

CpoolInfoItem::CpoolInfoItem( CpoolInfo* pool )
	: _poolInfo(pool)
	, SWFTreeItem("Cpool")
{
	this->setKind(SWFTreeItemKind::Cpool);
}

bool CpoolInfoItem::hasChildren() const 
{
	return false;
}
